var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const mongoose = require('mongoose');
require('./lib/db') 
const queryString = require('querystring')
const GOODS = require('./lib/model/goods')
const USERS = require('./lib/model/users')
const multiparty = require('multiparty')
const ORDER = require('./lib/model/orders');
const MANAGER = require('./lib/model/manager');
const fs = require('fs')
var app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));  // 设置公用的静态资源 public

// fs.rename('./upload/a.js', './public/javascripts/b.js', (err)=>{
//   if (!err) {
//     console.log('修改成功');
//   }else{
//     throw err
//   }
// })



// 商品模块



// GOODS.find({}).skip((pn-1)*size).limit(2).then((err,data) => {
//   console.log(err);
// })
// 商品列表
app.get('/list', (req,res)=>{
  let current = req.query.current || 1
  let pagesize = req.query.pagesize || 2000

  // skip  跳过几条数据
  // limit  4  
  GOODS.find({}, (err,allResult)=>{
    GOODS.find({}).skip((current-1)*pagesize).limit(pagesize).then((result)=>{
        res.json({
          code: 200,
          data: result,
          total: allResult.length
        })
    })
  })
  
})


// 商品详情
app.get('/detail', (req,res)=>{
  // 获取字符下标 indexOf()
  // 截取字符串  
  // substr(index)
  // split()  将字符串分割成数组

   // /detail?id=xxxx
  let str = req.url.substr(req.url.indexOf('?')+1)  // 截取以后的字符串   id=xxx&a=b&c=d
  let obj = queryString.parse(str)  // {id:xxx,a:''}
  /**
   * let str = req.url  // /detail?id=xxxx
    let index = str.indexOf('?')+1
    str = str.substr(index)  // 截取以后的字符串   id=xxx&a=b&c=d
    let obj = queryString.parse(str)  // {id:xxx,a:''}
   * 
   */
  // /detail?id=2
  // id前端传递给后端
  // 根据id查询商品
  // 查询到商品的详情数据之后，进行数据响应
  GOODS.findById(obj.id, (err, result)=>{
    res.json({
      code: 200,
      data: result
    })
  })
})

// 用户模块
// get post
// get请求  /detail?id=1   req.url 通过解析字符串   提取数据
// post请求  /login       req.body 获取数据     需要下载 body-parser  配置
// can't find property of phone
app.post('/login', (req,res)=>{ 
  let phone = req.body.phone
  let pwd = req.body.pwd
  USERS.findOne({phone: phone}, (err, result)=>{
    if (!err) {
      if (result) {
          if (result.pwd === pwd) {
            res.json({
              code: 200,
              msg: '登录成功',
              userId: result._id
            })
          }else{
            res.json({
              code: 400,
              msg: '密码错误'
            })
          }
      }else{
        new USERS({
          phone,
          pwd
        }).save((err, result)=>{
          res.json({
            code: 200,
            msg: '注册&登录成功',
            userId: result._id
          })
        })
      }
    }
  })
})

// 订单模块

// 生成订单

app.post('/createOrder', (req,res)=>{
  let orderData = req.body.orderData
  new ORDER(orderData).save((err)=>{
    if (err) {
      res.json({
        code: 400,
        msg: '创建失败'
      })
    }else{
      res.json({
        code: 200,
        msg: '订单生成成功'
      })
    }
  })
})

// 订单列表
app.post('/orderList', (req,res)=>{
  // 从数据库中拿订单列表
  // 解析成前端需要的内容
  // 返回 [] 数组中是对象  [{},{},{}]

  let arr = [] // 提前定义数组，方便将数据放到数组中，最终返回数组

  ORDER.find({userId: req.body.userId}, (err,result)=>{ // 从数据库中获取数据  result是获取到的数据，是一个[]
    if (!err) {  // 没有错误

      // 解析数据  
      /**
       *  [{
            id: 2,
            status: 1,
            goodsData: {
              mainImage: require("./../assets/phone2.jpg"),
              sku: "蓝色 4+256",
              title: "G8080 电竞版",
              price: 8000,
              seletedNum: 2,
            },
            createTime: "20222/7/30",
          }]
       */
      function fn (index) { // index就是下标

        // 如果index == 数组长度，说明已经解析完毕，返回数据给前端， 数据就是提前定义的err
        if (index == result.length) {
          res.json({
            code: 200,
            data: arr
          })
          return
        }

        // 数组中存放的就是对象,将解析好的内容，存放在对象中
        // result[index] 是数组的每一项
        /**
         *  {
                "_id" : ObjectId("630db7fe4432813b1db91093"),
                "userId" : "6309d8b0b056e73efe7b6899",
                "selectedSku" : {
                    "goodsId" : "6305c0520496194bf0480228",
                    "selectedNum" : 1,
                    "selectedSkuComb" : {
                        "id" : "6305c0520496194bf0480226",
                        "price" : 3,
                        "stock_num" : 1,
                        "s1" : 1,
                        "s2" : 2,
                        "_id" : "6305c0520496194bf0480233",
                        "properties" : [],
                        "property_price" : 0
                    }
                },
                "createTime" : ISODate("2022-08-30T06:45:53.602Z"),
                "status" : 1,
                "__v" : 0
            }
         */
        let obj = {}
        // 把订单的_id 作为数据的id
        obj.id = result[index]._id
        // 把订单的status 作为数据的status
        obj.status = result[index].status
        // 把订单的createTime 作为数据的reateTime
        obj.createTime = result[index].createTime

        // 找到订单表的对应price和数量，给obj.goodsData
        // 可以先不写，先打印看看是不是这个数据，看看每个数据的格式

        // result[index].selectedSku 是数组还是对象
        //  result[index].selectedSku[0].selectedSkuComb
        obj.goodsData = {
          'price': result[index].selectedSku[0].selectedSkuComb.price,
          'seletedNum':  result[index].selectedSku[0].selectedNum
        }
        // 订单表中有商品id
        let goodsId = result[index].selectedSku[0].goodsId
        // 根据id，在商品表中找到对应数据， data就是商品数据
        GOODS.findById(goodsId, (err,data)=>{
          // 如果没有错误，继续解析数据
          if(!err) {
            let sku = ''
            // 解析mainImage和title
            obj.goodsData.title = data.title
            obj.goodsData.mainImage = data.mainImage
            data.sku.tree.forEach(item => {
              item.v.forEach(elem => {
                if (result[index].selectedSku[0].selectedSkuComb[item.k_s] === elem.id) {
                  sku = sku + ' ' + elem.name
                }
              })
            })
            // 解析规格
            obj.goodsData.sku = sku
            // 对象的所有的属性就解析完毕。放到要给前端返回的数组中
            arr.push(obj)
            // 下标+1，继续调用函数，解析下一个
            index++
            fn(index)
          }else{ // 如果有错误，直接订单获取失败
            res.json({
              code: 400,
              data: '订单获取失败'
            })
          }
        })
      }
      fn(0)
    }else{ // 如果有错误，直接订单获取失败
      res.json({
        code: 400,
        data: '订单获取失败'
      })
    }
  })  
})

// 将待付款更改成已付款
app.post('/changeOrder', (req,res)=>{  
  // 拿到订单id
  // 根据id修改
  ORDER.findByIdAndUpdate(req.body.id, {status: 1}, (err)=>{
    if (!err) {
      res.json({
        code: 200,
        data: '付款成功'
      })
    }else{
      res.json({
        code: 400,
        data: '付款成功'
      })
    }
  })
})

// 管理员

app.post('/managerLogin', (req,res)=>{ 
  let username = req.body.username
  let password = req.body.password
  MANAGER.findOne({username, password}, (err, result)=>{
    if (!err) {
      if (result) {
        res.json({
          code: 200,
          msg: '登录成功',
          adminId: result.id
        })
      }else{
        res.json({
          code: 400,
          msg: '密码错误'
        })
      }
    }
  })
})

app.post('/upload', (req,res)=>{
  res.json({
    code: 200,
    msg: '上传成功'
  })
})
app.post('/mainImgUpload', (req,res)=>{
  let form = new multiparty.Form()
  form.uploadDir = './upload'

  form.parse(req, function (err,fields,files){
    console.log(files);
    // files是上传的文件信息 是个对象  对象中的 avatar是数组  数组的数据是文件   数组的数据是对象
    fs.rename(files.mainImage[0].path, './public/images/'+files.mainImage[0].originalFilename, (err)=>{
      if (!err) {
        console.log('修改成功');
        res.json({
          code: 200,
          msg: '上传成功',
          imgUrl: 'http://localhost:3005/images/' + files.mainImage[0].originalFilename
        })
      }else{
        throw err
      }
    })
  })
})

app.post('/bannerImgUpload', (req,res)=>{
  let form = new multiparty.Form()
  form.uploadDir = './upload'
  form.parse(req, function (err,fields,files){
    console.log(files);
    fs.rename(files.bannerImage[0].path, './public/images/'+files.bannerImage[0].originalFilename, (err)=>{
      if (!err) {
        console.log('修改成功');
        res.json({
          code: 200,
          msg: '上传成功',
          imgUrl: 'http://localhost:3005/images/' + files.bannerImage[0].originalFilename
        })
      }else{
        throw err
      }
    })
  })
})


app.post('/detailUpload', (req,res)=>{
  let form = new multiparty.Form()
  form.uploadDir = './upload'
  form.parse(req, function (err,fields,files){
    console.log(files);
    fs.rename(files.file[0].path, './public/images/'+files.file[0].originalFilename, (err)=>{
      if (!err) {
        console.log('修改成功');
        res.json({
          code: 200,
          msg: '上传成功',
          uploadedImageUrl: 'http://localhost:3005/images/' + files.file[0].originalFilename
        })
      }else{
        throw err
      }
    })
  })
})

app.post('/skuImgUpload', (req,res)=>{
  let form = new multiparty.Form()
  form.uploadDir = './upload'
  form.parse(req, function (err,fields,files){
    console.log(files);
    // files是上传的文件信息 是个对象  对象中的 avatar是数组  数组的数据是文件   数组的数据是对象
    fs.rename(files.skuImg[0].path, './public/images/'+files.skuImg[0].originalFilename, (err)=>{
      if (!err) {
        console.log('修改成功');
        res.json({
          code: 200,
          msg: '上传成功',
          imgUrl: 'http://localhost:3005/images/' + files.skuImg[0].originalFilename
        })
      }else{
        throw err
      }
    })
  })
})

app.post('/changeAdmin', (req,res)=>{  
  MANAGER.findByIdAndUpdate(req.body.adminInfo.id, {
    ...req.body.adminInfo
  },(err)=>{
    if (!err) {
      res.json({
        code: 200,
        data: '修改成功'
      })
    }else{
      res.json({
        code: 400,
        data: '修改失败'
      })
    }
  })
})

app.get('/getAdminInfo', (req,res)=>{
  MANAGER.find({}, (err,result)=>{
    if (!err) {
      res.json({
        code: 200,
        msg: '获取成功',
        info: {
          username: result[0].username,
          avatar: result[0].avatar
        }
      })
    }
  })
})

app.post('/goodsAdd', (req,res)=>{
  let data = req.body
  new GOODS(data).save((err,result)=>{
    if (!err) {
      res.json({
        code: 200,
        msg: '商品添加成功'
      })
    }else{
      res.json({
        code: 400,
        msg: '商品添加失败'
      })
    }
  })
})


app.post('/goodsDel', (req,res)=>{
  let data = req.body._id
  
  GOODS.deleteOne({
    id: data
  }, (err,result) => {
    if (!err) {
      res.json({
        code: 200,
        msg: '删除成功'
      })
    }else{
      res.json({
        code: 200,
        msg: '删除失败'
      })
    }
  })
})


app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;
